﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using TomanuExtensions;
using System.Diagnostics;
using RaytracerLib.MathLib.RootFinders;

namespace RaytracerLib.MathLib.Polynomials
{
    public class PolynomialSolver
    {
        private PolynomialSolveMethod m_polynomial_solve_method;
        private RootFinder m_root_finder;

        public PolynomialSolver(PolynomialSolveMethod a_polynomial_solve_method, RootFindingMethod a_root_finder_method)
        {
            m_polynomial_solve_method = a_polynomial_solve_method;
            m_root_finder = RootFinder.Create(a_root_finder_method);
        }

        public double SolveQuartic(double a_c0, double a_c1, double a_c2, double a_c3, double a_c4)
        {
            switch (m_polynomial_solve_method)
            {
                case PolynomialSolveMethod.Algebraic:
                {
                    return new PolynomialSolverAlgebraic(
                        new Polynomial(a_c0, a_c1, a_c2, a_c3, a_c4)).SolveAlgebraicQuarticOne();
                }
                case PolynomialSolveMethod.Sturm:
                {
                    return new PolynomialSolverAprox(
                        new Polynomial(a_c0, a_c1, a_c2, a_c3, a_c4), m_root_finder).SolveOne();
                }
                default:
                {
                    throw new NotImplementedException();
                }
            }
        }

        public double Solve(Polynomial a_p)
        {
            switch (m_polynomial_solve_method)
            {
                case PolynomialSolveMethod.Algebraic:
                {
                    Debug.Assert(a_p.Order <= 4);
                    return new PolynomialSolverAlgebraic(a_p).SolveAlgebraicQuarticOne();
                }
                case PolynomialSolveMethod.Sturm:
                {
                    return new PolynomialSolverAprox(a_p, m_root_finder).SolveOne();
                }
                default:
                {
                    throw new NotImplementedException();
                }
            }
        }
    }
}
